package main;

import java.io.IOException;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

import protocol.AsyncServerProtocol;

public class ConnectionHandler implements Runnable {

	private final Socket _socket;
	//private final Encoder _encoder;
	private final Tokenizer _tokenizer;
	@SuppressWarnings("rawtypes")
	private final AsyncServerProtocol _protocol;
	private final CharsetEncoder _encoder;

	public ConnectionHandler(Socket s, Charset charset, Tokenizer tokenizer,
			@SuppressWarnings("rawtypes") AsyncServerProtocol protocol) {
		_socket = s;
		_tokenizer = tokenizer;
		_protocol = protocol;
		_encoder = charset.newEncoder();
	}

	@SuppressWarnings("unchecked")
	public void run() {

		while (!_protocol.shouldClose() && !_socket.isClosed()
				&& !Thread.currentThread().isInterrupted()) {
			try {
				if (!_tokenizer.isAlive())
					_protocol.connectionTerminated();
				else {
					String msg = _tokenizer.nextToken();
					if (!msg.equals("")) {
						String ans = (String) _protocol.processMessage(msg);
						if (ans != null) {
							ByteBuffer tmp = this._encoder.encode(CharBuffer
									.wrap(ans));
							byte[] buf = tmp.array();
							_socket.getOutputStream().write(buf, 0, buf.length);
						}
					}
				}
			} catch (Exception e) {
				_protocol.connectionTerminated();
				break;
			}
		}
		try {
			Thread.sleep(1000);
			_socket.close();
		} catch (IOException ignored) {
		} catch (InterruptedException e) {
		}
		System.out.println("thread done");
	}

}